﻿using RightControl.Common;
using RightControl.IService;
using RightControl.Model;
using RightControl.WebApp.Areas.Admin.Controllers;
using System;
using System.Web.Mvc;
using AlibabaCollector;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.IO;
using KS3;
using KS3.Model;

namespace RightControl.WebApp.Areas.DataSrv.Controllers {
    public class ProductController : BaseController {
        public static IProductService productService { get; set; }
        public static IProductImgService productImgService { get; set; }
        public static ITranslationService translationService { get; set; }
        public static ISubProductService subProductService { get; set; }
        public static IBaseCategoryService baseCategoryService { get; set; }
        public static IExportFieldsService exportFieldsService { get; set; }
        public static ISubProductImageService subProductImageService { get; set; }
        public static ISubProductSizeService subProductSizeService { get; set; }
        public static IAttrOptionsService attrOptionService { get; set; }   

        public ProductController() {
            PageAnalyser.productService = productService;
            PageAnalyser.productImgService = productImgService;
            PageAnalyser.subProductImageService = subProductImageService;
            PageAnalyser.subProductSizeService = subProductSizeService;

            InterfaceAnalyser.productService = productService;
            InterfaceAnalyser.productImgService = productImgService;
            InterfaceAnalyser.subProductImageService = subProductImageService;
            InterfaceAnalyser.subProductSizeService = subProductSizeService;

        }

        public ActionResult Index(int? id, string category = "NZ") {
          
            IEnumerable<BasicFields> basicFields = attrOptionService.GetBasicFields(category);
            ViewData["OptionsData"] = SelectOptionsData(basicFields);

            List<ExportFields> exportFields = exportFieldsService.GetExportFields(category, 1);
            ViewData["category"] = category;
            ViewData["TableHead"] = exportFields;
            //ViewData["OptionsData"] = SelectOptionsData(exportFields);
            ViewData["BaseCategory"] = baseCategoryService.GetAllCategory();
            base.Initialize(id);
            return View();
        }

        public ActionResult ViewImages(int Id) {
            return View(GetProdcutImages(Id));
        }

        [HttpPost]
        public JsonResult FetchItem(string categoryCode, string oriProductUrls) {
            var tableHead = exportFieldsService.GetExportFields(categoryCode, 1);
            if (oriProductUrls.IsNotEmpty()) {
                String url = HttpUtility.UrlDecode(oriProductUrls);
                String[] urls = Regex.Split(url, "\n", RegexOptions.IgnoreCase);
                for (int i = 0; i < urls.Length; i++) {
                    url = urls[i].Split('?')[0];
                    InterfaceAnalyser.GetDetail(url, Operator.UserId, categoryCode, tableHead);
                    //   PageAnalyser.GetDetail(url, Operator.UserId, filter.CategoryCode, tableHead);
                }
            }
            return Json(SuccessTip());
        }

        /// <summary>
        /// 加载数据列表
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="pageInfo"></param>
        /// <returns></returns>
        [HttpGet]
        public JsonResult List(PageInfo pageInfo, ProductDetail filter) {
          
            filter.UserId = Operator.UserId;
            var result = productService.GetListByFilter(filter, pageInfo);

            List<Dictionary<string, string>> productResultList = new List<Dictionary<string, string>>();
            if (result != null && result.count > 0) {
                var tableHead = exportFieldsService.GetExportFields(filter.CategoryCode, 1);
                ViewData["TableHead"] = tableHead;
                Dictionary<string, string> rows, props;
                foreach (var item in result.data as List<ProductDetail>) {
                    rows = new Dictionary<string, string>();
                    props = SerializerHelper.JsonDeserialized<Dictionary<string, string>>(item.KeyAttributes);
                    props = props == null ? new Dictionary<string, string>() : props;
                    rows["Id"] = item.Id.ToString();
                    rows["OriProductUrl"] = item.OriProductUrl;
                    rows["ImageUrl"] = item.ImageUrl;
                    rows["Title"] = item.Title;
                    rows["SkuId"] = item.SkuId;
                    rows["Price"] = item.Price.ToString();
                    rows["UpdateOn"] = item.UpdateOn.ToString("yyyy-MM-dd HH:mm:ss");

                    if (props != null) {
                        if (filter.ProductType == 1) {
                            tableHead.ForEach(h => {
                                rows[h.FieldName] = props.ContainsKey(h.FieldName) ? props[h.FieldName] : "";
                            });
                        }
                        else {
                        }
                    }

                    productResultList.Add(rows);
                }
            }
            return Json(Pager.Paging(productResultList, result.count), JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public JsonResult updateSubProducts(int productId, List<SubProduct> subProdList) {
            AjaxResult result = new AjaxResult();
            if (subProductService.DeleteByProdcutId(productId)) {
                if (subProdList.IsNotEmpty()) {
                    subProdList.ForEach(p => {
                        p.CreateOn = DateTime.Now;
                        p.UpdateBy = Operator.UserId;
                    });
                    result = subProductService.SaveSubProducts(subProdList) > 0 ? SuccessTip() : ErrorTip();
                }
            }
            else {
                result = ErrorTip();
            }
            return Json(result, JsonRequestBehavior.AllowGet);
        }

        public ActionResult Edit(int Id) {
            ViewData["BaseCategory"] = baseCategoryService.GetAllCategory();

            return View(GetProdcutImages(Id));
        }

        private ProductDetail GetProdcutImages(int Id) {
            var model = productService.ReadModel(Id);
            if (model != null) {
                dynamic imagsRet = productImgService.GetListByFilter(new ProductImage(Id), new PageInfo(1, 10000));
                if (imagsRet != null && imagsRet.code == 0) {
                    ViewData["productImags"] = imagsRet.data;
                }
            }
            return model;
        }

        [HttpPost]
        public ActionResult MoveTo(List<ProdAttribute> prodAttibutes) {
            if (prodAttibutes.IsNotEmpty()) {
                foreach (var item in prodAttibutes) {
                    var model = GetLatestProdModel(item.Id, item.KeyAttributes);
                    var ajaxRet = TranslateDetails(model);
                    if (ajaxRet != null && ajaxRet.state.ToString() != ResultType.success.ToString()) {
                        return Json(ajaxRet, JsonRequestBehavior.AllowGet);
                    }
                }
                return Json(SuccessTip(), JsonRequestBehavior.AllowGet);
            }
            else {
                return Json(ErrorTip("请先勾选待移入产品库的产品!"), JsonRequestBehavior.AllowGet);
            }
        }

        private ProductDetail GetLatestProdModel(int Id, string KeyAttributes) {
            var model = productService.ReadModel(Id);
            var tableHead = exportFieldsService.GetExportFields(model.CategoryCode, 1);

            model.UpdateBy = Operator.UserId;
            string[] keyArrtributes = KeyAttributes.Split('^');
            if (keyArrtributes != null && keyArrtributes.Length > 0) {
                Dictionary<string, string> props = new Dictionary<string, string>();
                int idx = 0;
                foreach (var item in tableHead) {
                    props[item.FieldName] = keyArrtributes[idx++];
                }
                string newKeyAttributes = SerializerHelper.JsonSerialized<Dictionary<string, string>>(props);
                if (newKeyAttributes != model.KeyAttributes) {
                    model.KeyAttributes = newKeyAttributes;
                    productService.UpdateModel(model);
                }
            }
            return model;
        }

        private AjaxResult TranslateDetails(ProductDetail model) {
            HashSet<string> words = new HashSet<string>();
            //尺码维度翻译英文
            Dictionary<string, string> prodSizeAttributes = new Dictionary<string, string>();
            SubProductSize subProdSize = new SubProductSize() { ProductId = model.Id };
            List<SubProductSize> subProdSizeList = subProductSizeService.GetSubProductSizeList(subProdSize, new PageInfo(1, 100));
            if (subProdSizeList != null && subProdSizeList.Count > 0) {
                prodSizeAttributes = SerializerHelper.JsonDeserialized<Dictionary<string, string>>(subProdSizeList[0].KeyAttributes);
                if (prodSizeAttributes == null) {
                    return ErrorTip("请先点击【编辑】按钮，完成子商品颜色尺码设置!");
                }
            }

            Dictionary<string, string> keyAttributes = SerializerHelper.JsonDeserialized<Dictionary<string, string>>(model.KeyAttributes);

            SubProductImage subProdImage = new SubProductImage() { ProductId = model.Id };
            List<SubProductImage> subProdImagesRet = subProductImageService.GetSubProductImageList(subProdImage, new PageInfo(1, 100));

            Dictionary<string, string> translatedResult = new Dictionary<string, string>();
            Dictionary<string, string> fieldDic = new Dictionary<string, string>();
            Dictionary<string, string> subProdfieldDic = new Dictionary<string, string>();
            Dictionary<string, string> dhAttributes = new Dictionary<string, string>();
            Dictionary<string, BasicFields> translateDic = new Dictionary<string, BasicFields>();
            IEnumerable<BasicFields> basicFields = attrOptionService.GetBasicFields(model.CategoryCode);
            foreach (var item in basicFields) {
                if (item.FdType == 1) {
                    fieldDic[item.FieldName] = item.EngFieldNm;
                }
                else {
                    subProdfieldDic[item.FieldName] = item.EngFieldNm;
                }

                if (!string.IsNullOrEmpty(item.OptionVal)) {
                    string key = item.FdType == 2 ? item.OptionVal : item.Id;
                    translateDic[key] = item;
                }
            }

            string tmpKeyVal = "";
            foreach (var item in keyAttributes) {
                tmpKeyVal = fieldDic[item.Key].Replace(" ", "_");
                if (translateDic.ContainsKey(item.Value)) {
                    translatedResult[tmpKeyVal] = translateDic[item.Value].OptionEngNm != null ? translateDic[item.Value].OptionEngNm : translateDic[item.Value].OptionVal;
                    if (translateDic[item.Value].DhAttrId.IsNotEmpty()) {
                        dhAttributes[translateDic[item.Value].DhAttrId] = translateDic[item.Value].DhAttrValueId.IsNotEmpty() ? translateDic[item.Value].DhAttrValueId : translateDic[item.Value].OptionEngNm;
                    }
                }
                else {
                    translatedResult[tmpKeyVal] = item.Value;
                }
            }

            //更新sub_product_size 中KeyAttributes的字段为英文
            foreach (var prodSize in subProdSizeList) {
                if (translateDic.ContainsKey(prodSize.Size)) {
                    BasicFields trans = translateDic[prodSize.Size];
                    prodSize.DhAttribute = string.IsNullOrEmpty(trans.DhAttrId) ? "" : string.Format("{0},{1}", trans.DhAttrId, trans.DhAttrValueId);
                }

                foreach (KeyValuePair<String, String> item in prodSizeAttributes) {
                    prodSize.KeyAttributes = subProdfieldDic.ContainsKey(item.Key) ? prodSize.KeyAttributes.Replace(item.Key, subProdfieldDic[item.Key]) : prodSize.KeyAttributes;
                }
            }

            return updateProductToEngList(model, translatedResult, dhAttributes)
                              && updateSubProductToEngList(subProdImagesRet)
                              && subProductSizeService.UpdateSubProductSizes(subProdSizeList, "Size,DhAttribute,Price,KeyAttributes") ? SuccessTip() : ErrorTip();
        }
  
        public static Dictionary<string, string> SelectOptionsData(IEnumerable<BasicFields> fieldsList = null) {
            Dictionary<string, string> selectItemDic = new Dictionary<string, string>();
            if (fieldsList != null) {
                string curFieldName = "";
                StringBuilder candidateSb = new StringBuilder();
                foreach (var item in fieldsList) {
                    if (item.FdType ==1) {
                        if (curFieldName != item.FieldName) {
                            if (curFieldName.IsNotEmpty()) {
                                selectItemDic[curFieldName] = candidateSb.ToString().TrimEnd('^');
                            }
                            curFieldName = item.FieldName;
                            candidateSb.Clear();
                        }
                        candidateSb.AppendFormat("{0}${1}^", item.Id, item.OptionVal);
                    }                  
                }
                if (candidateSb.Length > 0) {
                    selectItemDic[curFieldName] = candidateSb.ToString().TrimEnd('^');
                }
            }
            return selectItemDic;
        }
        public static Dictionary<string, string> SelectOptionsData(List<ExportFields> fieldsList = null) {
            Dictionary<string, string> selectItemDic = new Dictionary<string, string>();
            if (fieldsList != null && fieldsList.Count > 0) {
                foreach (var item in fieldsList) {
                    if (!string.IsNullOrEmpty(item.Candidates)) {
                        selectItemDic[item.FieldName] = item.Candidates;
                    }
                }

            }
            return selectItemDic;
        }

        private Boolean updateProductToEngList(ProductDetail model, Dictionary<string, string> keyAttributes, Dictionary<string, string> dhAttributes) {
         
            model.ProductType = 2;
            model.UpdateOn = DateTime.Now;
            model.KeyAttributes = SerializerHelper.JsonSerialized(keyAttributes);
            model.DhAttributes = SerializerHelper.JsonSerialized(dhAttributes);
            List<string> titleList = new List<string>();

            StringBuilder sbTitle = new StringBuilder();
            var fieldsForTitle = exportFieldsService.GetFieldsForTitle(model.CategoryCode, 1);
            if (fieldsForTitle.IsNotEmpty()) {
                string val = "", keyVal = "";
                fieldsForTitle.ForEach(p => {                    
                    keyVal = p.EngFieldNm;
                    val = keyAttributes.ContainsKey(keyVal) ? keyAttributes[keyVal] : "";

                    if (sbTitle.Length + val.Length > 80) return;       //标题取权重最高字段，长度<80
                    sbTitle.Append(val + " ");
                });
            }
            model.Title = sbTitle.ToString();
            return productService.UpdateModel(model);
        }

        /// <summary>
        /// 子商品图片
        /// </summary>
        /// <param name="subProdImgList"></param>
        /// <param name="translatedResult"></param>
        /// <returns></returns>
        private Boolean updateSubProductToEngList(List<SubProductImage> subProdImgList) {
            if (subProdImgList.IsNotEmpty()) {
                HashSet<string> colorWords = new HashSet<string>();
                foreach (var item in subProdImgList) {
                    colorWords.Add(item.Color);
                }
                Dictionary<string, Translation> colorTranDic = translationService.GetWordsTranslation(colorWords);

                string value = "";
                foreach (var item in subProdImgList) {
                    if (colorTranDic.ContainsKey(item.Color)) {
                        value = colorTranDic[item.Color].TransEnglish;
                        //item.DhAttribute = string.IsNullOrEmpty(translatedResult[item.Color].DhAttrId) ? "" : string.Format("{0},{1}", translatedResult[item.Color].DhAttrId, translatedResult[item.Color].DhAttrValueId);
                    }
                    else {
                        value = item.Color;
                    }

                    //item.SkuId = item.SkuId.Replace(item.Color, value);
                    item.Color = value;
                    item.UpdateOn = DateTime.Now;
                }

                return subProductImageService.UpdateSubProducts(subProdImgList, "DhAttribute,Color,UpdateOn") > 0;
            }
            else {
                return true;
            }
        }

        [HttpPost]
        public ActionResult updateProductBatch(List<ProductDetail> productParam, string categoryCode) {
            if (productParam != null && productParam.Count > 0) {
                var tableHead = exportFieldsService.GetExportFields(categoryCode, 1);

                productParam.ForEach(p => {
                    p.UpdateBy = Operator.UserId;
                    string[] keyArrtributes = p.KeyAttributes.Split('^');
                    if (keyArrtributes != null && keyArrtributes.Length > 0) {
                        p.Title = "";// keyArrtributes[0];
                        Dictionary<string, string> props = new Dictionary<string, string>();
                        int idx = 0;
                        foreach (var item in tableHead) {
                            props[item.FieldName] = keyArrtributes[idx++];
                        }
                        p.KeyAttributes = SerializerHelper.JsonSerialized<Dictionary<string, string>>(props);
                    }
                });
            }
            var result = productService.UpdateByIdBatch(productParam, "KeyAttributes,UpdateBy,UpdateOn") > 0 ? SuccessTip() : ErrorTip();
            return Json(result);
        }

        /// <summary>
        /// 用于初始化数据
        /// </summary>
        private void UpdateAllProductsByDescp() {
            var presult = productService.GetAll() as List<ProductDetail>;
            var tableHead = exportFieldsService.GetExportFields("NZ", 1);
            presult.ForEach(p => {
                string descp = p.Description;

                Dictionary<string, string> descpDic = SerializerHelper.JsonDeserialized<Dictionary<string, string>>(descp);
                Dictionary<string, string> props = new Dictionary<string, string>();
                tableHead.ForEach(t => {
                    props[t.FieldName] = descpDic.ContainsKey(t.FieldName) ? descpDic[t.FieldName] : "";
                });
                p.KeyAttributes = SerializerHelper.JsonSerialized<Dictionary<string, string>>(props);
            });
            productService.UpdateByIdBatch(presult, "KeyAttributes,UpdateBy,UpdateOn");
        }

        [HttpPost]
        public ActionResult updateProduct(ProductDetail model) {
            model.UserId = Operator.UserId;
            model.CreateBy = Operator.UserId;
            model.UpdateOn = DateTime.Now;
            model.UpdateBy = Operator.UserId;
            var result = productService.UpdateModel(model) ? SuccessTip() : ErrorTip();
            return Json(result);
        }

        /// <summary>
        /// 删除按钮
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Delete(int Id) {
            //删除商品时,同时删除子Sku图片 尺寸记录
            Boolean delMode = productService.DeleteModel(Id);
            productImgService.DeleteByProdcutId(Id, Operator.UserId, 0);
            //subProductService.DeleteByProdcutId(Id);
            subProductImageService.DeleteByProdcutId(Id, Operator.UserId);
            subProductSizeService.DeleteByProdcutId(Id, Operator.UserId);
            var result = delMode ? SuccessTip() : ErrorTip();
            return Json(result);
        }

        public ActionResult CreateFtpDirByDay() {
            FTPHelper ftpHelper = new FTPHelper("/AutoUpload/");
            string today = DateTime.Now.ToString("yyyyMMdd");
            ftpHelper.MakeDir(today);

            ftpHelper = new FTPHelper(string.Format("/AutoUpload/{0}/", today));
            ftpHelper.MakeDir("Clothes");
            return Json("OK", JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <returns></returns>
        public JsonResult UploadFiles(int productId, int imgType, string categoryCode) {
            uploadFile _uploadFile = new uploadFile();
            try {
                var file = Request.Files[0]; //获取选中文件
                var filecombin = file.FileName.Split('.');
                if (file == null || string.IsNullOrEmpty(file.FileName) || file.ContentLength == 0 || filecombin.Length < 2) {
                    _uploadFile.errno = -1;
                    _uploadFile.src = "";
                    _uploadFile.msg = "上传出错!请检查文件名或文件内容";
                    return Json(_uploadFile);
                }
                else if (!IsFileExtValid(filecombin[1])) {
                    _uploadFile.errno = -1;
                    _uploadFile.msg = "上传出错!请检查文件格式";
                    return Json(_uploadFile);
                }

                //定义本地路径位置
                string localPath = Server.MapPath("~/Upload/img/");
                string filePathName = string.Empty;

                string tmpName = Server.MapPath("~/Upload/img/");
                var tmp = RightControl.Common.Common.RandomCode(5) + file.FileName;
                var tmpIndex = 0;
                //判断是否存在相同文件名的文件 相同累加1继续判断  
                while (System.IO.File.Exists(tmpName + tmp)) {
                    tmp = filecombin[0] + "_" + ++tmpIndex + "." + filecombin[1];
                }
                //不带路径的最终文件名  
                filePathName = tmp;

                if (!System.IO.Directory.Exists(localPath))
                    System.IO.Directory.CreateDirectory(localPath);

                string filePath = Path.Combine(tmpName, filePathName);
                file.SaveAs(filePath);   //保存图片（文件夹)

                string bucketName = "productimage";
                string objKeyNameFileData = string.Format("U{0}/{1}/{2}", Operator.UserId, DateTime.Now.ToString("yyyyMMdd"), filePathName);
                FileInfo file2 = new FileInfo(filePath);
                PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objKeyNameFileData, file2);
                CannedAccessControlList cannedAcl = new CannedAccessControlList(CannedAccessControlList.PUBLICK_READ);
                putObjectRequest.setCannedAcl(cannedAcl);

                PutObjectResult putObjectResult = new PutObjectResult();
                if (putObjectResult != null) {
                    string imgUrl = string.Format("http://{0}/{1}/{2}", "", bucketName, objKeyNameFileData);
                    //_uploadFile.src = Path.Combine("/Upload/img/", endPoint); 

                    System.IO.File.Delete(filePath);
                    _uploadFile.imgId = productImgService.InsertModel(new ProductImage(productId, imgUrl, imgType, Operator.UserId, 100));
                    _uploadFile.data.Add(imgUrl);
                    _uploadFile.msg = "上传成功";
                }
                else {
                    _uploadFile.msg = "上传失败";
                }

                //string uploadSvr = Configs.GetValue("UploadServer");
                //string remotePath = DateTime.Now.ToString("yyyyMMdd");
                //imgUrl = string.Format("http://{0}/AutoUpload/{1}/Clothes/{2}", uploadSvr, remotePath, filePathName);
                //FTPHelper ftpHelper = new FTPHelper(string.Format("/AutoUpload/{0}/Clothes", remotePath));
                //ftpHelper.Upload(filePath);
                //_uploadFile.src = Path.Combine("/Upload/img/", filePathName); //name = Path.GetFileNameWithoutExtension(file.FileName),   // 获取文件名不含后缀名  
                //_uploadFile.data.Add(imgUrl);
                //_uploadFile.msg = "上传成功";


                return Json(_uploadFile);
            }
            catch (Exception ex) {
                _uploadFile.errno = -1;
                _uploadFile.src = "error" + ex.Message;
                return Json(_uploadFile, JsonRequestBehavior.AllowGet);
            }
        }

        private bool IsFileExtValid(string fileExt) {
            bool isPhoto = false;
            string[] allowedExtensions = { ".gif", ".png", ".jpeg", ".jpg", ".bmp", "webp" };
            for (int i = 0; i < allowedExtensions.Length; i++) {
                if (string.Compare(fileExt, allowedExtensions[i], StringComparison.CurrentCultureIgnoreCase) == 0) {
                    isPhoto = true;
                    break;
                }
            }
            return !isPhoto;
        }

        /// <summary>
        /// 压缩下载图片
        /// </summary>
        /// <returns></returns>
        public void DownImages(int productId) {
            string downPhotoPath = string.Format("{0}\\{1}\\", Configs.GetValue("ImgTempDir"), productId);
            string zipFilePath = string.Format(@"{0}\images_{1}.zip", Configs.GetValue("ImgTempDir"), productId);
            FileInfo fileInfo = new FileInfo(zipFilePath);
            if (!fileInfo.Exists) {
                var prodImage = new ProductImage(productId);
                dynamic ret = productImgService.GetListByFilter(prodImage, new PageInfo(1, 1000));

                if (ret != null) {
                    var prodImgList = ret.data as List<ProductImage>;
                    if (prodImgList != null && prodImgList.Count > 0) {
                        List<string> imgUrls = new List<string>();
                        prodImgList.ForEach(pImg => {
                            imgUrls.Add(pImg.ImgUrl);
                        });

                        ImageDown.SaveImages(imgUrls, downPhotoPath);
                        ZipHelper.Zip(downPhotoPath, zipFilePath);
                    }
                }
            }

            fileInfo = new FileInfo(zipFilePath);
            if (fileInfo.Exists) {
                Response.Clear();
                Response.ClearContent();
                Response.ClearHeaders();
                Response.AddHeader("Content-Disposition", string.Format("attachment;filename=image_{0}.zip", productId));
                Response.AddHeader("Content-Length", fileInfo.Length.ToString());
                Response.AddHeader("Content-Transfer-Encoding", "binary");
                Response.ContentType = "application/octet-stream";
                Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");
                Response.WriteFile(fileInfo.FullName);
                Response.Flush();
                Response.End();
            }
        }
    }
}